import {
    BroadcastRequest,
    BroadcastResponse,
    BroadcastResponseStatus,
    BroadcastType,
    Controller,
    ControllerNo,
    GuiId
} from "./model/ControllerOpt";
import {
    Attrs,
    CaluAttrStr,
    CaluType,
    CombinationUIInfo,
    CombitionRet,
    LevelUpType,
    MaterialInfo,
    RewardType,
    SpecialEffectType,
    UnitPosition
} from "../type/Type";
import {DataRouter} from "../frame/dataSource/DataRouter";
import {Util} from "../utils/Util";
import {ControllerBroadcast} from "./ControllerBroadcast";
import {GoodsSerializeBody, ItemLoadType, SerializeBody, SerializeLoadType} from "./model/SerializeBody";
import {
    AchievementBeneficiaryType,
    CombinationData,
    ItemData,
    PlayerAttribute,
    PositionType,
    UnitAttribute
} from "../frame/dataSource/DataModel";
import {GlobalEnv} from "../utils/GlobalEnv";
import {ConfigKey, CosumeSetting, QualitySetting} from "../constant/ConfigConstant";
import Configer from "../frame/apiModel/config/Configer";
import {DataRouterUtil} from "../utils/router/DataRouterUtil";
import {Logger} from "../frame/apiModel/config/Logger";
import {PlayerModel} from "../frame/apiModel/adapterModel/model4/PlayerModel";
import {ItemDataKey, PlayerDataKey, UnitDataKey} from "../frame/dataSource/DataSource";
import {ItemModel} from "../frame/apiModel/adapterModel/model3/ItemModel";
import {ItemJson} from "../frame/apiModel/model/StoreJson";
import {LocModel} from "../frame/apiModel/base/LocModel";
import {ModelFactory} from "../frame/apiModel/adapterModel/model5/ModelFactory";
import {UnitModel} from "../frame/apiModel/adapterModel/model3/UnitModel";
import {CodeUtil} from "../frame/codeAdapter/CodeUtil";
import {PlayerFactory} from "../frame/PlayerFactory";
import {TaskController} from "./TaskController";
import {ThreeChooseOneModel} from "../../gui/code/model/GuiModel";
import {ModelType} from "../frame/apiModel/adapter/adapterInterface/model5/IModelFactory";
import UnitUtil from "../utils/UnitUtil";
import {PositionConfig, UIConfigKey} from "../constant/UIConfig";
import {FinalKey} from "../constant/FinalConstant";
import {TimeController} from "./TimeController";

export class GoodController implements Controller {
    private static goodController: GoodController = new GoodController();
    // private static _goodsBags: GoodsItemInfo[][] = [];
    // private static _goodEquips: GoodsItemInfo[][] = [];
    // private static _goodItemMaps: Map<item, GoodsItemInfo> = new Map<item, GoodsItemInfo>();
    //
    // private static _itemBags: GoodsItemInfo[][][] = [];
    // private static _itemBagsIndex: number[] = [];
    // // 羁绊数组
    // private static _goodCombinations: Map<unit, CombinationInfo>[] = [];

    getControllerNo(): number {
        return ControllerNo.GoodController;
    }
    // string是goodsId
    // 里面的属性是在initAbilityEffectTrigger中添加的，而在caluAbilityAttributes时移除
    // private static _goodAttributes: Map<unit, Map<string, Attribute>> = new Map<unit, Map<string, Attribute>>();
    static getInstance() {
        return GoodController.goodController;
    }
    init() {
        ControllerBroadcast.getInstance().startListen(GoodController.getInstance());
    }
    setItemBagsByIndex(unit: UnitModel, index: number, itemModel: ItemModel[]) {
        const itemBags = unit.data[UnitDataKey.unitBag];
        itemBags[index] = itemModel;
        return itemBags;
    }
    getItemBagsByPlayer(unit: UnitModel) {
        const itemBags = unit?.data[UnitDataKey.unitBag];
        return itemBags;
    }
    getItemBagIndex(unit: UnitModel) {
        const index = unit?.data[UnitDataKey.unitBagsIndex];
        return index;
    }
    getItemBagByIndex(unit: UnitModel, index: number) {
        const itemBags = this.getItemBagsByPlayer(unit);
        if (itemBags) {
            const itemBag = itemBags[index];
            return itemBag;
        }
        return [];
    }
    getItemBagIndexByPlayer(unit: UnitModel) {
        const index = unit.data[UnitDataKey.unitBagsIndex];
        return index;
    }
    setItemBagIndexByPlayer(unit: UnitModel, index: number) {
        unit.data[UnitDataKey.unitBagsIndex] = index;
    }
    // todo 【需要被回退】
    reflushItemBag (unit: UnitModel) {
        const itemBagIndex = this.getItemBagIndexByPlayer(unit);
        const itemModels = ModelFactory.getInstance().getItemModelsByUnit(unit);
        this.setItemBagsByIndex(unit, itemBagIndex, itemModels)
    }
    resumeGood(itemModel: ItemModel, loc: LocModel) {
        if (itemModel) {
            // const item = ModelFactory.getInstance().createItemInPoint(goodsInfo, loc);
            itemModel.loc = loc;
            itemModel.show = true;
            return itemModel;
        } else {
            Logger.toastError(`只有装备可以被丢弃！`);
        }
    }

    buyItem(itemId: string, buyUnitId: string, sellUnitId: string) {
        const buyUnit = ModelFactory.getInstance().getModel(buyUnitId, ModelType.unit) as UnitModel;
        const sellUnit = ModelFactory.getInstance().getModel(sellUnitId, ModelType.unit) as UnitModel;
        if (buyUnit?.isValid() && sellUnit?.isValid()) {
            const player = PlayerFactory.getInstance().getUnitOwner(buyUnit);
            if (player?.isNotEndPlaying()) {
                const itemData = DataRouter.getItemDataByItemId(itemId);
                const goldcost = itemData.goldcost;
                const singleBuyNum = itemData.singleBuyNum ? itemData.singleBuyNum : 0;
                const lumbercost = itemData.lumbercost;
                let ret = true;
                if ((goldcost && goldcost > player.gold )) {
                    ret = false;
                }
                if (lumbercost && lumbercost > player.lumber) {
                    ret = false;
                }
                if (ret) {
                    if (goldcost) {
                        player.gold -= goldcost;
                    }
                    if (lumbercost) {
                        player.lumber -= lumbercost;
                    }
                    const itemJson: ItemJson = { id: itemId, n: singleBuyNum, cd: 0, lv: 0 };
                    ModelFactory.getInstance().createItemInUnit(itemJson, buyUnit, sellUnit, true);
                    Logger.toastProduct('购买成功！')
                } else {
                    Logger.toastProduct('货币不足, 购买失败！')
                }
            }
        } else {
            Logger.toastProduct('单位已失效, 购买失败！')
        }
    }


    loadByJson(json: GoodsSerializeBody, player: PlayerModel) {
        const heroGoods: ItemJson[] = [];
        const archiveIndex = player.data[PlayerDataKey.archiveIndex];
        const boxGoods: ItemJson[] = [];


        const hero = GlobalEnv.getHero(player);
        const box = GlobalEnv.getBox(player);

        this.mapGoodSerialize(archiveIndex, SerializeLoadType.current_global, (key, index, type) => {
            const value: ItemJson = json[key];
            if (!CodeUtil.isNullOrZero(value?.id)) {
            } else {
                return;
            }
            const newIndex = index;
            switch (type) {
                case ItemLoadType.hg: {
                    heroGoods[newIndex] = value;
                    break;
                }
                case ItemLoadType.bg: {
                    boxGoods[newIndex] = value;
                    break;
                }
                case ItemLoadType.gb: {
                    const item = ModelFactory.getInstance().createItemInPoint(value, hero.loc, true)
                    if (item) {
                        this.insertShowItemToBag(player, item, newIndex);
                    }
                    break;
                }
                case ItemLoadType.eq: {
                    const item = ModelFactory.getInstance().createItemInPoint(value, hero.loc, true)
                    if (item) {
                        const position = item.template.position;
                        this.insertShowItemToEquip(player, item, position);
                    }
                    break;
                }
            }
        })
        const maxLen = Configer.getConfig(ConfigKey.maxItemSlot)
        if (hero) {
            const itemBags: ItemModel[] = [];
            for (let i = 0; i < maxLen; i++) {
                const itemJson = heroGoods[i];
                if (itemJson) {
                    const item = ModelFactory.getInstance().createItemInPoint(itemJson, hero.loc, true)
                    itemBags.push(item);
                }
            }
            // this.setItemBagsByIndex(hero,0, itemBags);
            this.setUnitByItems(hero, itemBags, true);
        }

        // const itemBags1: ItemModel[] = [];
        // for (let i = 0; i < heroGoods.length; i++) {
        //     const itemJson = heroGoods[i];
        //     if (itemJson) {
        //         const item = ModelFactory.getInstance().createItemInPoint(itemJson, hero.loc, true)
        //         itemBags1.push(item);
        //     }
        // }
        // this.setItemBagsByIndex(hero,1, itemBags1);

        if (box) {
            const itemBoxs: ItemModel[] = [];
            for (let i = 0; i < maxLen; i++) {
                const itemJson = boxGoods[i];
                if (itemJson) {
                    const item = ModelFactory.getInstance().createItemInPoint(itemJson, box.loc, true)
                    itemBoxs.push(item);
                }
            }
            this.setUnitByItems(box, itemBoxs, true);
        }
    }


    setUnitByItems (unit: UnitModel, itemModels: ItemModel[], bindPlayer: boolean = false) {
        if (unit?.isValid()) {
            const player = PlayerFactory.getInstance().getUnitOwner(unit);
            const maxNum = Configer.getConfig(ConfigKey.maxItemSlot)
            if (itemModels) {
                for (let i = 0; i < maxNum; i ++) {
                    const itemModel = itemModels[i];
                    if (itemModel) {
                        const goodId = itemModel.strId;
                        if (!CodeUtil.isNullOrZero(goodId)) {
                            ModelFactory.getInstance().unitAddItem(unit, itemModel);
                            if (bindPlayer) {
                                DataRouterUtil.bindItemBlong(itemModel, player);
                            }
                        }
                    }
                }
            }
        }
    }


    setUnitByGoodInfos (unit: UnitModel, goodInfos: ItemJson[], bindPlayer: boolean = false) {
        const goods = goodInfos;
        if (unit?.isValid()) {
            const player = PlayerFactory.getInstance().getUnitOwner(unit);
            const maxNum = Configer.getConfig(ConfigKey.maxItemSlot)
            if (goods) {
                for (let i = 0; i < maxNum; i ++) {
                    const good = goods[i];
                    if (good) {
                        const goodId = good.id;
                        if (!CodeUtil.isNullOrZero(goodId)) {
                            const item = ModelFactory.getInstance().createItemInUnit(good, unit);
                            if (bindPlayer) {
                                DataRouterUtil.bindItemBlong(item, player);
                            }
                        }
                    }
                }
            }
        }
    }


    /**
     * attribute不提前注册，在获取时如果取不到就取默认的
     * 对于英雄来说这个属性会在第一次调用caluAttribute()后注册
     */
    caluGoodAttributes(unit: UnitModel): Attrs {
        let goodAttrs: Attrs;
        const useBag = Configer.getConfig(ConfigKey.useGoodsBar);
        if (!CodeUtil.isNullOrZero(useBag)) {
            goodAttrs = this.getGoodAttrsByBags(unit);
        } else {
            goodAttrs = this.getGoodAttrsByItemSlot(unit);
        }

        const combinationAttr = this.caluGoodCombination(unit);

        const attrs = Util.sumAttributes(goodAttrs, combinationAttr, CaluType.add);

        return attrs;
    }
    getGoodAttrsByBags(unit: UnitModel): Attrs {
        let unitAttr = new UnitAttribute();
        let playerAttr = new PlayerAttribute();
        let attrs = { unitAttr, playerAttr };
        const isHero = GlobalEnv.isInHeroGroup(unit);
        if (isHero) {
        } else {
            return attrs
        }
        const player = PlayerFactory.getInstance().getUnitOwner(unit);
        const goodEquips = this.getGoodsEquipByPlayer(player);
        const maxGoodsEquipNum = Configer.getConfig(ConfigKey.maxGoodsEquipNum) as number;
        for (let i = 0; i < maxGoodsEquipNum; i ++) {
            const position = i + 1
            const itemModel = goodEquips[position];
            if (itemModel) {
                const goodData = itemModel.template;
                if (goodData) {
                    const lv = itemModel.data[ItemDataKey.forgLv];
                    const forgAddRadix = Configer.getConfig(ConfigKey.forgAddRadix);
                    const num = (1 + forgAddRadix * lv)
                    const tempAttr = this.getAttrByGoodData(goodData, num);
                    attrs = Util.sumAttributes(attrs, tempAttr, CaluType.add);

                    const affixStr = itemModel.data[ItemDataKey.itemAffix];
                    const affixAttr = UnitUtil.getItemAffixAttr(affixStr);
                    attrs = Util.sumAttributes(attrs, affixAttr, CaluType.add);
                }
            }
        }
        return attrs
    }
    getGoodAttrsByItemSlot(unit: UnitModel): Attrs {
        let unitAttr = new UnitAttribute();
        let playerAttr = new PlayerAttribute();
        let attrs = { unitAttr, playerAttr };
        unit.mapItems((item) => {
            const goodData = DataRouter.getItemDataByItemId(item.strId)
            if (goodData) {
                const lv = item.data[ItemDataKey.forgLv];
                const forgAddRadix = Configer.getConfig(ConfigKey.forgAddRadix);
                const num = (1 + forgAddRadix * lv)
                const tempAttr = this.getAttrByGoodData(goodData, num);
                attrs = Util.sumAttributes(attrs, tempAttr, CaluType.add);
            }

            const affixStr = item.data[ItemDataKey.itemAffix];
            const affixAttr = UnitUtil.getItemAffixAttr(affixStr);
            attrs = Util.sumAttributes(attrs, affixAttr, CaluType.add);

            return false;
        });
        return attrs;
    }

    successCheck(player: PlayerModel, canLvUp: boolean, canLvDown: boolean, upQualityPro: number, downQualityPro: number): LevelUpType {
        let upQualityProNum = 0, downQualityProNum = 0;
        let type = LevelUpType.none;
        if (!CodeUtil.isNullOrZero(upQualityPro)) {
            upQualityProNum = upQualityPro;
        }
        if (!CodeUtil.isNullOrZero(downQualityPro)) {
            downQualityProNum = downQualityPro;
        }

        if (!CodeUtil.isNullOrZero(downQualityPro) || !CodeUtil.isNullOrZero(upQualityPro)) {
        } else {
            return type;
        }

        const random = player.getRandomInt(0, 100);
        if (random < downQualityProNum) {
            type = LevelUpType.failed;
            if (canLvDown) {
                type = LevelUpType.failed;
            } else {
                type = LevelUpType.failedButNone;
            }

        } else if (random <= (downQualityProNum + upQualityProNum)) {
            type = LevelUpType.success;
            if (canLvUp) {
                type = LevelUpType.success;
            } else {
                type = LevelUpType.successButNone;
            }
        } else {
            type = LevelUpType.unChange;
        }
        return  type
    }

    itemLevelUp(activeUnit: UnitModel, player: PlayerModel, itemModel: ItemModel, upQualityPro: number, downQualityPro: number, returnItemId: string): boolean {
        const goodId = itemModel.strId;
        const goodData = DataRouter.getItemDataByItemId(goodId);

        const returnFun = () => {
            const itemJson: ItemJson = { id: returnItemId, n: 0, cd: 0, lv: 0 };
            ModelFactory.getInstance().createItemInUnit(itemJson, activeUnit)
        }

        if (goodData) {
        } else {
            Logger.toastProduct(`当前物品无法升级`, player);
            returnFun();
            return false;
        }
        let retId;
        const lastItemId = GoodController.getInstance().levelUpItemByFamilyIdCheck(activeUnit, player, goodId, 0);
        const nextItemId = GoodController.getInstance().levelUpItemByFamilyIdCheck(activeUnit, player, goodId, 0);

        const type = this.successCheck(player, !CodeUtil.isNullOrZero(nextItemId), !CodeUtil.isNullOrZero(lastItemId), upQualityPro, downQualityPro);
        let pointStr;

        let needReturn = false;
        switch (type) {
            case LevelUpType.success: {
                retId = nextItemId;
                pointStr = `升级成功，等级上升！`;
                break;
            }
            case LevelUpType.failed: {
                retId = lastItemId;
                pointStr = `升级失败，等级下降！`;
                break;
            }
            case LevelUpType.failedButNone: {
                pointStr = `物品等级已经最低`;
                break;
            }
            case LevelUpType.successButNone: {
                pointStr = `物品等级已经最高`;
                break;
            }
            case LevelUpType.none: {
                pointStr = `当前物品无法升级`;
                break;
            }
            case LevelUpType.unChange: {
                pointStr = `升级失败，等级不变！`;
                break;
            }
        }
        if (pointStr) {
            Logger.toastProduct(pointStr, player)
        }
        if (retId) {
            GoodController.getInstance().removeGoods(activeUnit, itemModel);
            const itemJson: ItemJson = { id: retId, n: 0, cd: 0, lv: 0 };
            ModelFactory.getInstance().createItemInUnit(itemJson, activeUnit)
            return true;
        } else if (needReturn)  {
            returnFun();
        }
        return false;
    }
    insertAttrByGoodData(unit: UnitModel, item: ItemModel) {
        this.reflushItemBag(unit);
        this.addGoodCombinationByUnit(unit, item);
        // 获取新成就后广播给单位处理器 重新计算属性
        const request: BroadcastRequest = { broadcastType: BroadcastType.addCaluTaskByUnit, controllerNo: ControllerNo.UnitController, data: { unit: unit, caluAttrStr: CaluAttrStr.good } }
        ControllerBroadcast.getInstance().broadcast(request);
    }
    getAttrByGoodData(goodData: ItemData, num: number): Attrs {
        // Util.loggerInDev(`物品数量:${num}`, LogType.goodDev)
        return  DataRouterUtil.getAttrByAttrInterface(goodData?.attrId, num);
    }

    copyGoods(unit: UnitModel, newUnit: UnitModel) {
        unit.mapItems(
            (item: ItemModel, index: number) => {
                ModelFactory.getInstance().unitAddItem(newUnit, item);
                return false;
            }
        );
        const player = PlayerFactory.getInstance().getUnitOwner(newUnit);
        newUnit.data[UnitDataKey.unitBag] = unit.data[UnitDataKey.unitBag];
        newUnit.data[UnitDataKey.unitBagsIndex] = unit.data[UnitDataKey.unitBagsIndex];
        newUnit.data[UnitDataKey.unitEquip] = unit.data[UnitDataKey.unitEquip];
        newUnit.data[UnitDataKey.goodCombination] = unit.data[UnitDataKey.goodCombination];


        const request: BroadcastRequest = { broadcastType: BroadcastType.addStoreTask, controllerNo: ControllerNo.StoreController, data: { player, no: ControllerNo.GoodController } }
        ControllerBroadcast.getInstance().broadcast(request);
        // const goodInfos = Util.getGoodInfosByUnit(unit);
        // Util.setUnitByGoodInfos(newUnit, goodInfos);
    }
    notify(request: BroadcastRequest): BroadcastResponse {
        const ret: BroadcastResponse = { controllerNo: this.getControllerNo(), data: {}, status: BroadcastResponseStatus.success };
        const type = request.broadcastType;
        const data = request.data;
        switch (type) {
            case BroadcastType.serialize: {
                const player: PlayerModel = data.player;
                const serializeBody: SerializeBody = this.serialize(player);
                ret.data = { serializeBody };
                break;
            }
            case BroadcastType.caluGoodAttributes: {
                const unit: UnitModel = data.unit;
                const attribute = this.caluGoodAttributes(unit);
                ret.data = { attribute };
                break;
            }
            case BroadcastType.copyGoods: {
                const unit: UnitModel = data.unit;
                const newUnit: UnitModel = data.newUnit;
                this.copyGoods(unit, newUnit);
                break;
            }
            case BroadcastType.getGoodsBag: {
                const player: PlayerModel = data.player;
                const goodsBag = this.getGoodsBagByPlayer(player);
                ret.data = { goodsBag }
                break;
            }
            case BroadcastType.getGoodsEquip: {
                const player: PlayerModel = data.player;
                const goodsEquip = this.getGoodsEquipByPlayer(player);
                ret.data = { goodsEquip }
                break;
            }
            case BroadcastType.mapGoodsAddEffect: {
                const player: PlayerModel = data.player;
                this.mapAddEquipEffect(player)
                break;
            }
            default :
                ret.status = BroadcastResponseStatus.failed;
                break;
        }
        return ret;
    }

    getItemModelsByUnit (unit: UnitModel): ItemModel[] {
        if (unit?.isValid()) {
            const goods: ItemModel[] = [];
            unit.mapItems( (item, index) => {
                goods[index] = item;
                return false;
            })
            return goods;
        }
        return []
    }

    serialize(player: PlayerModel): GoodsSerializeBody {
        const hero = GlobalEnv.getHero(player);
        const archiveIndex = player.data[PlayerDataKey.archiveIndex];
        const goodsSerializeBody: GoodsSerializeBody = player.data[PlayerDataKey.storeCurrent][ControllerNo.GoodController];

        const heroGoods = this.getItemModelsByUnit(hero);

        const box = GlobalEnv.getBox(player);
        const boxGoods = this.getItemModelsByUnit(box);
        const goodsBag = this.getGoodsBagByPlayer(player);
        const goodsEquip = this.getGoodsEquipByPlayer(player);

        this.mapGoodSerialize(archiveIndex, SerializeLoadType.current_global, (key, index, type) => {
            let good: ItemModel;
            switch (type) {
                case ItemLoadType.hg: {
                    good = heroGoods[index];
                    break;
                }
                case ItemLoadType.bg: {
                    good = boxGoods[index];
                    break;
                }
                case ItemLoadType.gb: {
                    good = goodsBag[index];
                    break;
                }
                case ItemLoadType.eq: {
                    good = goodsEquip[index];
                    break;
                }
            }
            if (good?.isValid()) {
                if (!CodeUtil.isNullOrZero(good.template?.save)) {
                    goodsSerializeBody[key] = good.getJson();
                } else {
                    goodsSerializeBody[key] = '';
                }
            } else {
                goodsSerializeBody[key] = '';
            }
        })

        return goodsSerializeBody;
    }
    // getItemFromBag (player: player, itemId: string) {
    //     const hero = GlobalEnv.getHero(player);
    //     const itemInfo = this.getItemInfoFromBag(player, itemId);
    //     const playerId = GetPlayerId(player);
    //     let success = false;
    //     if (itemInfo) {
    //         if (itemInfo.n > 1) {
    //             itemInfo.n = itemInfo.n - 1;
    //             success = true;
    //         } else if (itemInfo.n === 1) {
    //             const arr = GoodController.goodsBags[playerId];
    //             const index = arr.indexOf(itemInfo);
    //             arr.splice(index, 1);
    //             success = true;
    //         }
    //     }
    //     if (success) {
    //         const slotNum = this.getItemNullSlot(hero);
    //         if (slotNum) {
    //             UnitAddItemToSlotById(hero, itemId, slotNum);
    //         } else {
    //             Util.loggerInDev('物品栏已满', LogType.product, ToastType.text, player);
    //         }
    //     }
    // }
    // getItemNullSlot(unit: unit) {
    //     for (let i = 0; i < 6; i++) {
    //         let item = UnitItemInSlot(unit, i);
    //         if (!IsHandle(item)) {
    //             return i;
    //         }
    //     }
    // }
    insertShowItemToBag (player: PlayerModel, item: ItemModel, index: number = -1) {
        // let goodInfo = item.getJson();
        const ret = this.insertGoodsInfoToBag(player, item, index);
        if (ret) {
            if(item) {
                item.loc = new LocModel(0, 0)
                item.show = false;
            }
            return true
        }
        return false;
    }
    clearUnitGoodSlot(unit: UnitModel) {
        unit.mapItems((item) => {
            ModelFactory.getInstance().unitRemoveItem(unit, item);
            return false;
        })
    }
    removeGoods(unit: UnitModel, item: ItemModel) {
        ModelFactory.getInstance().unitRemoveItem(unit, item);
    }

    reflushEquipBar (player: PlayerModel) {
        const updateData = { guiId: GuiId.equipBar, player: player };
        const request: BroadcastRequest = { broadcastType: BroadcastType.updateGui, controllerNo: ControllerNo.GuiController, data: updateData }
        ControllerBroadcast.getInstance().broadcast(request);
    }
    reflushGoodsBar (player: PlayerModel) {
        const updateData = { guiId: GuiId.goodsBar, player: player };
        const request: BroadcastRequest = { broadcastType: BroadcastType.updateGui, controllerNo: ControllerNo.GuiController, data: updateData }
        ControllerBroadcast.getInstance().broadcast(request);
    }
    insertGoodsInfoToBag (player: PlayerModel, itemModel: ItemModel, index: number = -1) {
        let ret = false;
        const hero = GlobalEnv.getHero(player);
        player.mapBags(
            (targetItem, index) => {
                const itemData = targetItem?.template;
                if (!CodeUtil.isNullOrZero(itemData?.stackable)) {
                    const itemStrId = targetItem?.strId;
                    const tempStrId = itemModel?.strId;
                    if (itemStrId === tempStrId) {
                        targetItem.charges = targetItem.charges + itemModel.charges;
                        ModelFactory.getInstance().unitRemoveItem(hero, itemModel);
                        ret = true;
                        return true
                    }
                }
                return false
            }
        )

        if (ret) {
            this.reflushGoodsBar(player);
            const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player, no: ControllerNo.GoodController } }
            ControllerBroadcast.getInstance().broadcast(req);
            return  true;
        }

        const currentNum = this.goodCurrentNum(player);

        const maxGoodsBagNum = Configer.getConfig(ConfigKey.maxGoodsBagNum);
        if (currentNum >= maxGoodsBagNum && itemModel?.isValid()) {
            return false;
        }
        const goodsBags = player.data[PlayerDataKey.goodsBag];
        let newIndex: number;
        if (index && index >= 0) {
            newIndex = index
        } else {
            newIndex = this.goodFirstNullIndex(player);
        }
        goodsBags[newIndex] = itemModel;
        this.reflushGoodsBar(player);
        const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player, no: ControllerNo.GoodController } }
        ControllerBroadcast.getInstance().broadcast(req);
        return true;
    }
    insertShowItemToEquip (player: PlayerModel, itemModel: ItemModel, position: number) {
        this.insertGoodsInfoToEquip(player, itemModel, position);
        if(itemModel) {
            itemModel.loc = new LocModel(0, 0)
            itemModel.show = false;
        }
    }
    insertGoodsInfoToEquip (player: PlayerModel, itemModel: ItemModel, position: number) {
        const hero = GlobalEnv.getHero(player);
        if (hero?.isValid()) {
            const goodEquips = hero.data[UnitDataKey.unitEquip];
            const oldItemModel = goodEquips[position];
            goodEquips[position] = itemModel;
            const combinationItem = itemModel ? itemModel : oldItemModel;
            this.addGoodCombinationByUnit(hero, combinationItem);
            this.reflushEquipBar(player);
            this.reflushGoodsBar(player);
            const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player: player, no: ControllerNo.GoodController } }
            ControllerBroadcast.getInstance().broadcast(req);

            const request: BroadcastRequest = { broadcastType: BroadcastType.addCaluTaskByUnit, controllerNo: ControllerNo.UnitController, data: { unit: hero, caluAttrStr: CaluAttrStr.good } }
            ControllerBroadcast.getInstance().broadcast(request);

            this.mapAddEquipEffect(player);

            return oldItemModel;
        }
    }

    getEffectPositionByEquipPosition(position: PositionType): UnitPosition | undefined {
        const equipAdapts = Configer.getUIConfig(UIConfigKey.EquipAdapt) as PositionConfig[];
        const maxGoodsEquipNum = Configer.getConfig(ConfigKey.maxGoodsEquipNum) as number;

        for (let i = 0; i < maxGoodsEquipNum; i++) {
            const equipAdapt = equipAdapts[i];
            if (!CodeUtil.isNullOrZero(equipAdapt)) {
                if (equipAdapt.position === position) {
                    return equipAdapt.unitPosition;
                }
            }
        }
    }
    mapAddEquipEffect(player: PlayerModel) {
        const hero = GlobalEnv.getHero(player);
        const foreverPeriodic = Configer.getFinal(FinalKey.foreverPeriodic) as number;
        const record = player.data[PlayerDataKey.equipRecord];

        if (hero?.isValid()) {
            const goodEquips = hero.data[UnitDataKey.unitEquip];
            const maxGoodsEquipNum = Configer.getConfig(ConfigKey.maxGoodsEquipNum) as number;
            for (let i = 0; i < maxGoodsEquipNum; i++) {
                const equips = goodEquips[i];
                const equipsId = equips?.template?.id
                const oldEffect =  record[i];


                const oldItemId = oldEffect?.itemId;
                if (oldEffect) {
                    if (oldItemId === equipsId) {
                        continue;
                    } else {
                        ModelFactory.getInstance().destroy(oldEffect.effectModel, ModelType.effect);
                        record[i] = undefined;
                    }
                }

                if (equips?.isValid && equips.isValid()) {
                    const template = equips.template;
                    const decoration = template?.decoration;
                    if (!CodeUtil.isNullOrZero(decoration)) {
                        const decorationScale = template.decorationScale;
                        const unitPosition = this.getEffectPositionByEquipPosition(i);
                        if (unitPosition) {
                            const newEffect = TimeController.addSpecialEffectByResourceIdFun(hero, decoration, foreverPeriodic, undefined, unitPosition, SpecialEffectType.unit, decorationScale);
                            if (newEffect) {
                                record[i] = { itemId: equipsId, effectModel: newEffect };
                            }
                        }
                    }
                }
            }
        } 
    }

    decomposeGoods(index: number, player: PlayerModel) {
        const goodBags = player.data[PlayerDataKey.goodsBag];
        const itemModel = goodBags[index];
        const hero = GlobalEnv.getHero(player);
        if (itemModel?.isValid()) {
            const lv = itemModel.data[ItemDataKey.forgLv];
            const forgSetting: (CosumeSetting & { decomposeId: string })[] = Configer.getConfig(ConfigKey.forgSetting);
            const forgSet = lv && forgSetting[lv];
            if (forgSet) {
                const decomposeId = forgSet.decomposeId;
                if (!CodeUtil.isNullOrZero(decomposeId)) {
                    TaskController.getInstance().reward(hero, hero, RewardType.bag, decomposeId)
                }
            }
            const quality = itemModel.template?.quality;
            const qualitySetting: QualitySetting[] = Configer.getConfig(ConfigKey.qualitySetting);
            const qualitySet = quality && qualitySetting[quality];
            if (qualitySet) {
                const decomposeId = qualitySet.decomposeId;
                if (!CodeUtil.isNullOrZero(decomposeId)) {
                    TaskController.getInstance().reward(hero, hero, RewardType.bag, decomposeId)
                }
            }
            ModelFactory.getInstance().unitRemoveItem(hero, itemModel);

            this.reflushGoodsBar(player)
            const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player: player, no: ControllerNo.GoodController } }
            ControllerBroadcast.getInstance().broadcast(req);
        } else {
            Logger.toastProduct(`您点的太快了!`, player)
        }
    }
    washGoods(index: number, player: PlayerModel) {
        const goodBags = player.data[PlayerDataKey.goodsBag];
        const itemModel = goodBags[index];
        const hero = GlobalEnv.getHero(player);
        if (itemModel?.isValid()) {
            const washSetting: CosumeSetting = Configer.getConfig(ConfigKey.washSetting);
            const id = washSetting.cosumeId;
            const num = washSetting.cosumeNum;
            const success = washSetting.success;
            const failed = washSetting.failed;
            const type = this.successCheck(player, true, true, success, failed);

            let pointStr;
            let bChange = false;
            let changeFun: () => void;

            switch (type) {
                case LevelUpType.success: {
                    changeFun = () => {
                        DataRouterUtil.addNewAffixToItem(itemModel);
                    }
                    bChange = true;
                    pointStr = `洗炼成功！`;
                    break;
                }
                case LevelUpType.failed: {
                    changeFun = () => {
                        itemModel.data[ItemDataKey.itemAffix] = '';
                    }
                    bChange = true;
                    pointStr = `洗炼失败，词缀清空！`;
                    break;
                }
                case LevelUpType.failedButNone:
                case LevelUpType.successButNone:
                case LevelUpType.none: {
                    pointStr = `当前物品无法洗炼！`;
                    break;
                }
                case LevelUpType.unChange: {
                    pointStr = `洗炼失败，词缀不变！`;
                    bChange = true;
                    break;
                }
            }

            if (bChange) {
                const ret = ModelFactory.getInstance().consumItemOnUnit(hero, id, true, num);
                if (ret) {
                    if (pointStr) {
                        Logger.toastProduct(pointStr, player)
                    }
                    changeFun && changeFun();
                    this.reflushGoodsBar(player)
                    const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player: player, no: ControllerNo.TaskController } }
                    ControllerBroadcast.getInstance().broadcast(req);
                } else {
                    Logger.toastProduct(`洗炼所需材料不足`, player)
                }
            } else {
                if (pointStr) {
                    Logger.toastProduct(pointStr, player)
                }
            }
        } else {
            Logger.toastProduct(`您点的太快了!`, player)
        }
    }
    forgGoods(index: number, player: PlayerModel) {
        const goodBags = player.data[PlayerDataKey.goodsBag];
        const itemModel = goodBags[index];
        const hero = GlobalEnv.getHero(player);
        if (itemModel?.isValid()) {
            const lv = itemModel.data[ItemDataKey.forgLv];
            const forgSeting: CosumeSetting[] = Configer.getConfig(ConfigKey.forgSetting);
            const currentSet = forgSeting[lv];
            if (currentSet) {
                const id = currentSet.cosumeId;
                const num = currentSet.cosumeNum;
                const success = currentSet.success;
                const failed = currentSet.failed;

                let pointStr;
                let bChange = false;
                let bFailed = false;

                let changeFun: () => void;
                const type = this.successCheck(player, !CodeUtil.isNullOrZero(success), !CodeUtil.isNullOrZero(failed), success, failed);
                switch (type) {
                    case LevelUpType.success: {
                        changeFun = () => {
                            itemModel.data[ItemDataKey.forgLv] = lv + 1;
                        }
                        bChange = true;
                        pointStr = `锻造成功，等级上升！`;
                        break;
                    }
                    case LevelUpType.failed: {
                        changeFun = () => {
                            itemModel.data[ItemDataKey.forgLv] = lv - 1;
                        }
                        bFailed = true;
                        bChange = true;
                        pointStr = `锻造失败，等级下降！`;
                        break;
                    }
                    case LevelUpType.failedButNone: {
                        pointStr = `锻造等级已达到最低！`;
                        break;
                    }
                    case LevelUpType.successButNone: {
                        pointStr = `锻造等级已达到最高！`;
                        break;
                    }
                    case LevelUpType.none: {
                        pointStr = `当前物品无法锻造！`;
                        break;
                    }
                    case LevelUpType.unChange: {
                        pointStr = `锻造失败，等级不变！`;
                        bChange = true;
                        break;
                    }
                }

                if (bChange) {
                    let skipUseItem = false;
                    if (bFailed) {
                        const itemId = Configer.getFinal(FinalKey.forgProtectItemId);
                        skipUseItem = ModelFactory.getInstance().consumItemOnUnit(hero, itemId, true, 1);
                    }
                    let ret;
                    if (skipUseItem) {
                        pointStr = `锻造失败，消耗了一张降级保护卷！`
                    } else {
                        ret = ModelFactory.getInstance().consumItemOnUnit(hero, id, true, num);
                    }
                    if (ret) {
                        if (pointStr) {
                            Logger.toastProduct(pointStr, player)
                        }
                        changeFun && changeFun();
                        this.reflushGoodsBar(player)
                        const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player: player, no: ControllerNo.GoodController } }
                        ControllerBroadcast.getInstance().broadcast(req);
                    } else {
                        if (skipUseItem) {
                            if (pointStr) {
                                Logger.toastProduct(pointStr, player)
                            }
                            this.reflushGoodsBar(player)
                            const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player: player, no: ControllerNo.GoodController } }
                            ControllerBroadcast.getInstance().broadcast(req);
                        } else {
                            Logger.toastProduct(`锻造所需材料不足`, player)
                        }
                    }
                } else {
                    if (pointStr) {
                        Logger.toastProduct(pointStr, player)
                    }
                }
            } else {
                Logger.toastProduct(`当前锻造等级已达到最高`, player)
            }
        } else {
            Logger.toastProduct(`您点的太快了!`, player)
        }
    }



    sellGoods(index: number, player: PlayerModel) {
        const hero = GlobalEnv.getHero(player);
        const goodBags = player.data[PlayerDataKey.goodsBag];
        if (hero) {
            const itemModel = goodBags[index];
            if (itemModel?.isValid()) {
                const goodsId = itemModel.strId;
                let num = itemModel.charges;
                if (num === 0) {
                    num = 1;
                }
                const goodsData = DataRouter.getItemDataByItemId(goodsId);
                const cost = goodsData?.goldcost ? (goodsData.goldcost / 2) : 0;
                const coin = cost * num;
                UnitUtil.addCoin(hero, player, coin);
                goodBags[index] = undefined;
                const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player, no: ControllerNo.GoodController } }
                ControllerBroadcast.getInstance().broadcast(req);
                this.reflushGoodsBar(player)
            } else {
                Logger.toastProduct(`您点的太快了!`, player)
            }
        } else {
            Logger.toastProduct(`当前英雄不处于空闲状态，请稍后再试`, player)
        }
    }
    unUseGoods (position: number, player: PlayerModel) {
        const hero = GlobalEnv.getHero(player);
        if (hero) {
            const goodEquips = hero.data[UnitDataKey.unitEquip];
            const tempItem = goodEquips[position];
            if (tempItem) {
                const ret = this.insertShowItemToBag(player, tempItem);
                if (ret) {
                    this.insertGoodsInfoToEquip(player, undefined, position);
                    const req: BroadcastRequest = {
                        controllerNo: ControllerNo.StoreController,
                        broadcastType: BroadcastType.addStoreTask,
                        data: {player, no: ControllerNo.GoodController}
                    }
                    ControllerBroadcast.getInstance().broadcast(req);
                    const request: BroadcastRequest = { broadcastType: BroadcastType.addCaluTaskByPlayer, controllerNo: ControllerNo.UnitController, data: { player: player, type: AchievementBeneficiaryType.hero } }
                    ControllerBroadcast.getInstance().broadcast(request);
                }
            } else {
                Logger.toastProduct(`您点的太快了!`, player)
            }
        } else {
            Logger.toastProduct(`当前英雄不处于空闲状态，请稍后再试!`, player)
        }
    }
    tidyUpItems (player: PlayerModel) {
        const nullIndexArr = [];
        player.mapBags((itemModel, index) => {
            if (itemModel?.isValid()) {
                if (nullIndexArr.length > 0) {
                    const nullIndex = nullIndexArr.shift();
                    this.insertGoodsInfoToBag(player, undefined, index);
                    this.insertGoodsInfoToBag(player, itemModel, nullIndex);
                    nullIndexArr.push(index);
                }
            } else {
                nullIndexArr.push(index);
            }
            return false;
        })
    }
    checkLevel(unit: UnitModel, goodData: ItemData) {
        if (goodData) {
        } else {
            Logger.toastError('捡装备时 没有对应的物品信息');
            return false;
        }
        const isHero = GlobalEnv.isInHeroGroup(unit);
        const player = PlayerFactory.getInstance().getUnitOwner(unit);
        if (isHero) {
            // const wearLevel = goodData.wear_level;
            // const unitTransNum = GetUnitUserData(unit);
            // if (unitTransNum < wearLevel) {
            //     SysToastUtil.toastProduct(`该装备需要${wearLevel}转生才能携带!`, player)
            //     return false;
            // }
            const goodLevel = goodData.wear_level;
            const unitLevel = unit.level;
            if (unitLevel < goodLevel) {
                Logger.toastProduct(`该装备需要${goodLevel}级才能携带!`, player)
                return false;
            }
        }
        return true;
    }
    useGoods(index: number, player: PlayerModel) {
        const hero = GlobalEnv.getHero(player);
        const goodBags = player.data[PlayerDataKey.goodsBag];
        if (hero) {
            const itemModel = goodBags[index];
            if (itemModel?.isValid()) {
                const goodsData = itemModel.template;
                const ret = this.checkLevel(hero, goodsData);
                if (ret) {
                } else {
                    return;
                }
                const position = goodsData?.position;
                this.insertShowItemToBag(player, undefined, index);
                const oldGoodsInfo = this.insertGoodsInfoToEquip(player, itemModel, position);
                if (oldGoodsInfo) {
                    this.insertShowItemToBag(player, oldGoodsInfo);
                }
                const req: BroadcastRequest = {
                    controllerNo: ControllerNo.StoreController,
                    broadcastType: BroadcastType.addStoreTask,
                    data: {player, no: ControllerNo.GoodController}
                }
                ControllerBroadcast.getInstance().broadcast(req);
                const request: BroadcastRequest = { broadcastType: BroadcastType.addCaluTaskByPlayer, controllerNo: ControllerNo.UnitController, data: { player: player, type: AchievementBeneficiaryType.hero } }
                ControllerBroadcast.getInstance().broadcast(request);
            } else {
                Logger.toastProduct(`您点的太快了!`, player)
            }
        } else {
            Logger.toastProduct(`当前英雄不处于空闲状态，请稍后再试`, player)
        }
    }
    dropGoods(index: number, player: PlayerModel) {
        const hero = GlobalEnv.getHero(player);
        const goodBags = player.data[PlayerDataKey.goodsBag];
        if (hero) {
            const itemModel = goodBags[index];
            if (itemModel?.isValid()) {
                const loc = hero.loc;
                this.resumeGood(itemModel, loc);
                DataRouterUtil.bindItemBlong(itemModel, player)
                goodBags[index] = undefined;
                const req: BroadcastRequest = { controllerNo: ControllerNo.StoreController, broadcastType: BroadcastType.addStoreTask, data: { player, no: ControllerNo.GoodController } }
                ControllerBroadcast.getInstance().broadcast(req);
                this.reflushGoodsBar(player)
            } else {
                Logger.toastProduct(`您点的太快了!`, player)
            }
        } else {
            Logger.toastProduct(`当前英雄不处于空闲状态，请稍后再试`, player)
        }
    }
    goodFirstNullIndex(player: PlayerModel) {
        const goodBags = player.data[PlayerDataKey.goodsBag];
        const maxGoodsBagNum = Configer.getConfig(ConfigKey.maxGoodsBagNum);
        for (let i = 0; i < maxGoodsBagNum; i ++) {
            const itemModel = goodBags[i];
            if (itemModel && itemModel?.isValid()) {
            } else {
                return i;
            }
        }
    }
    goodCurrentNum(player: PlayerModel) {
        const goodBags = player.data[PlayerDataKey.goodsBag];
        let num = 0;
        const maxGoodsBagNum = Configer.getConfig(ConfigKey.maxGoodsBagNum);
        for (let i = 0; i < maxGoodsBagNum; i ++) {
            const itemModel = goodBags[i];
            if (itemModel && itemModel?.isValid()) {
                num = num + 1;
            }
        }
        return num;
    }
    getGoodsBagByPlayer(player: PlayerModel) {
        const goodBags = player.data[PlayerDataKey.goodsBag];
        return goodBags;
    }
    getGoodsEquipByPlayer(player: PlayerModel) {
        const hero = GlobalEnv.getHero(player);
        if (hero) {
            const equipBars = hero.data[UnitDataKey.unitEquip];
            return equipBars;
        }
        return [];
    }
    // addToGoodBags(player: player, index: number, item: item) {
    //     const playerId = GetPlayerId(player);
    //     const goodBags = GoodController.goodsBags[playerId];
    //     const goodsInfo = Util.getGoodInfo(item);
    //     goodBags[index] = goodsInfo;
    // }

    getAttrByCombinationData(combination: CombinationData) {
        // Util.loggerInDev(`物品数量:${num}`, LogType.goodDev)
        return  DataRouterUtil.getAttrByAttrInterface(combination?.attrId, 1);
    }
    caluGoodCombination(unit: UnitModel): Attrs {
        let unitAttr = new UnitAttribute();
        let playerAttr = new PlayerAttribute();
        let attrs = { unitAttr, playerAttr };
        const player = PlayerFactory.getInstance().getUnitOwner(unit);
        if (player.isNotEndPlaying()) {
        } else {
            return attrs;
        }
        const goodCombination = unit.data[UnitDataKey.goodCombination];
        CodeUtil.mapObj(goodCombination, (key, value) => {
            if (value.attrs) {
                attrs = Util.sumAttributes(attrs, value.attrs, CaluType.add);
            }
        })
        return attrs;
    }
    getGoodCombinationByUnit(unit: UnitModel) {
        const player = PlayerFactory.getInstance().getUnitOwner(unit);
        if (player.isNotEndPlaying()) {
        } else {
            return;
        }
        const combination = unit.data[UnitDataKey.goodCombination];
        return combination;
    }

    addGoodCombinationByUnit(unit: UnitModel, item: ItemModel) {
        const itemStr = DataRouterUtil.getItemStr(item?.strId)
        const goodCombinationDatas = DataRouter.getCombinationDatasByItemId(itemStr);

        if (goodCombinationDatas) {
        } else {
            return;
        }

        const combinationInfos: MaterialInfo[] = [];

        const itemArrs = this.getCombinationGoodArr(unit);
        for (let i = 0; i < itemArrs.length; i++) {
            const itemModel = itemArrs[i];
            const id = DataRouterUtil.getItemStr(itemModel.strId);
            const materialInfo: MaterialInfo = {
                id: id,
                num: itemModel.charges,
            }
            combinationInfos.push(materialInfo);
        }

        const itemUseLadder = Configer.getConfig(ConfigKey.itemUseLadder);
        const checkRets = DataRouterUtil.checkToCombitionByMaterialInfos(combinationInfos, goodCombinationDatas, itemUseLadder);

        const goodCombination = unit.data[UnitDataKey.goodCombination];

        // if (goodCombination) {
        //     CodeUtil.mapObj(goodCombination, (key, value) => {
        //         const ret = checkRets[key]
        //         if (ret) {
        //         } else {
        //             goodCombination[key] = undefined;
        //         }
        //         return false
        //     })
        // }


        // 给操作物品的单位添加套装Id
        CodeUtil.mapObj(checkRets, (key, value) => {
            goodCombination[key] = value;
            return false;
        })

        // print(JSON.stringify(goodCombination))
    }

    getCombinationGoodArr(unit: UnitModel) {
        const ret: ItemModel[] = [];
        unit.mapEquips((item, index) => {
            ret.push(item);
            return false;
        })
        unit.mapItems((item, index) => {
            ret.push(item);
            return false;
        })
        return ret
    }


    levelUpItemByFamilyIdCheck (unit: UnitModel, player: PlayerModel, itemId: string, bAdd: 0 | 1) {
        if (itemId) {
            const nextItemRet = DataRouterUtil.getNextItemIdByFamilyId(player, itemId, bAdd);
            return nextItemRet;
        } else {
            Logger.toastError(`请传入正确的物品家族`);
        }
    }

    // 只用来做ui显示的model  物品与角色羁绊最大的不同点在于物品基于itemId显示对应的，人物羁绊需要显示所有的
    // 羁绊列表需要从短到长 把羁绊id翻到外面  单位id翻到里面
    getAllGoodCombinationBodyByPlayer(unit: UnitModel, itemId: string): CombinationUIInfo {
        const unitCheck = unit?.isValid();
        if (unitCheck) {
        } else {
            return;
        }
        const goodCombination = unit.data[UnitDataKey.goodCombination];

        const combinationIds: { [key: string]: CombitionRet } = {};
        const itemIds: { [key: string]: number } = {};
        const itemArr: ItemModel[] = this.getCombinationGoodArr(unit);
        // 遍历所有物品判断羁绊
        for (let itemIndex = 0; itemIndex < itemArr.length; itemIndex++) {
            const item = itemArr[itemIndex];
            const tempItemId = DataRouterUtil.getItemStr(item.strId);
            if (tempItemId) {
            } else {
                continue;
            }

            // 如果单位重复只取一个
            const num = itemIds[tempItemId];

            if (num && num >= 0) {
                itemIds[tempItemId] = num + 1
            } else {
                itemIds[tempItemId] = 1;
            }
        }

        const tempItemId = DataRouterUtil.getItemStr(itemId);

        const combinationDatas = DataRouter.getCombinationDatasByItemId(tempItemId);
        if (combinationDatas) {
            for (let combinationIndex = 0; combinationIndex < combinationDatas.length; combinationIndex++) {
                const combinationData = combinationDatas[combinationIndex];
                if (combinationData) {
                    // const currentName = combinationData.name;
                    const combinationId = combinationData.id;
                    const rets = combinationIds[combinationId];

                    if (rets) {
                        continue;
                    } else {
                        if (goodCombination && goodCombination[combinationId]) {
                            combinationIds[combinationId] = goodCombination[combinationId]
                        } else {
                            combinationIds[combinationId] = { attrs: undefined, effects: undefined, successNum: 0, currentNum: 0 };
                        }
                    }
                }
            }
        }

        return { combinationIds: combinationIds, ids: itemIds };
    }

    getUiChooseItem = (useUnit: UnitModel, itemId: string) => {
        const models: ThreeChooseOneModel[] = [];
        const itemData = DataRouter.getItemDataByItemId(itemId);
        if (itemData) {
        } else {
            Logger.toastError(`三选一时没有配置对应的奖励组 ${itemId}`);
            return;
        }
        const rewardId = itemData.type_id;
        // const configNum: number = Configer.getConfig(ConfigKey.chooseOneNum)
        const group = TaskController.getInstance().getRewardGroupByRewardId(useUnit, rewardId);

        for (let i = 0; i < 3; i++) {
            const rewardItem = group[i];
            const id = rewardItem.itemId;
            let model: ThreeChooseOneModel;
            const itemData = DataRouter.getItemDataByItemId(id);
            if (itemData) {
                const art = DataRouterUtil.getIconUrlByIconData(itemData)
                model = { Art: art, descript: itemData.Ubertip, id: itemData.id, name: itemData.Name, reward: undefined };
            }
            if (model) {
                models.push(model)
            }
            // models.push({ Art: Configer.getUIConfig(ResourceKeyachBarBoard), descript: '详情！！！', id: 'e004', name: '测试道具' })
        }
        return models;
    }

    mapGoodSerialize = (index: number, bAll: SerializeLoadType, callBack: (key: string, index: number, type: ItemLoadType) => void) => {

        const archiveFun = (archiveIndex: number) => {
            let heroPrefix = 'hg';
            let boxPrefix = 'bg';
            let eqPrefix = 'eq';

            heroPrefix = `${heroPrefix}${archiveIndex}_`;
            boxPrefix = `${boxPrefix}${archiveIndex}_`;
            eqPrefix = `${eqPrefix}${archiveIndex}_`;

            const maxItemSlot = Configer.getConfig(ConfigKey.maxItemSlot);
            for (let i = 0; i < maxItemSlot; i++) {
                const strIndex = `${i + 1}`;
                const prefix: string = heroPrefix;
                const key = prefix + strIndex;
                callBack(key, i, ItemLoadType.hg);
            }

            for (let i = 0; i < maxItemSlot; i++) {
                const strIndex = `${i + 1}`;
                const prefix: string = boxPrefix;
                const key = prefix + strIndex;
                callBack(key, i, ItemLoadType.bg);
            }

            // 装备数组从1开始
            const maxGoodsEquipNum = Configer.getConfig(ConfigKey.maxGoodsEquipNum) as number;
            for (let i = 0; i < maxGoodsEquipNum; i++) {
                const strIndex = `${i + 1}`;
                const prefix: string = eqPrefix;
                const key = prefix + strIndex;
                callBack(key, i, ItemLoadType.eq);
            }
        }

        const globalFun = () => {
            const maxGoodsBagNum = Configer.getConfig(ConfigKey.maxGoodsBagNum);
            for (let i = 0; i < maxGoodsBagNum; i++) {
                const strIndex = `${i + 1}`;
                const prefix: string = `gb_`;
                const key = prefix + strIndex;
                callBack(key, i, ItemLoadType.gb);
            }
        }

        switch (bAll) {
            case SerializeLoadType.current_global: {
                globalFun();
            }
            case SerializeLoadType.current_archive: {
                const archiveIndex = index;
                archiveFun(archiveIndex);
                break;
            }
            case SerializeLoadType.all_global: {
                globalFun();
            }
            case SerializeLoadType.all_archive: {
                const maxArchiveNum = Configer.getConfig(ConfigKey.maxArchiveNum);
                for (let i = 0; i < maxArchiveNum; i++) {
                    const tempIndex = i + 1;
                    archiveFun(tempIndex);
                }
                break;
            }
        }

    }
}